using System.Collections.Generic;

namespace SmartMathLibrary
{
    /// <summary>
    /// Interface to implement an Aggregate class.
    /// </summary>
    public interface IAggregate
    {
        /// <summary>
        /// Gets or sets the data of the aggregate.
        /// </summary>
        /// <value>The data of the aggregate.</value>
        List<double> Data { get; set; }

        /// <summary>
        /// Gets the number of items of the aggregate.
        /// </summary>
        /// <value>The number of items of the aggregate.</value>
        int Count { get; }

        /// <summary>
        /// Determines whether the [aggregate is empty].
        /// </summary>
        /// <returns>
        /// 	<c>true</c> if the [aggregate is empty]; otherwise, <c>false</c>.
        /// </returns>
        bool IsEmptyAggregate();

        /// <summary>
        /// Converts the data of the aggregate to an array of numbers.
        /// </summary>
        /// <returns>The converted array of numbers.</returns>
        double[] ToArray();

        /// <summary>
        /// Sorts the list of aggregate numbers.
        /// </summary>
        void Sort();

        /// <summary>
        /// Adds a new element to the aggregate.
        /// </summary>
        /// <param name="item">The item to add.</param>
        void AddElement(double item);

        /// <summary>
        /// Removes the element at the specified position.
        /// </summary>
        /// <param name="index">The specified position of the item to delete.</param>
        void RemoveElement(int index);

        /// <summary>
        /// Removes the element with the specified value from the aggregate.
        /// </summary>
        /// <param name="item">The specified value of the item to remove.</param>
        void RemoveElement(double item);

        /// <summary>
        /// Removes all elements from the aggregate.
        /// </summary>
        void RemoveAllElements();

        /// <summary>
        /// Determines whether the current aggregate instance [contains] [the specified value].
        /// </summary>
        /// <param name="value">The value to check.</param>
        /// <returns>
        /// 	<c>true</c> if the current aggregate instance [contains] [the specified value]; otherwise, <c>false</c>.
        /// </returns>
        bool Contains(double value);

        /// <summary>
        /// Determines whether the specified aggregate [is a subset of] [the current aggregate instance].
        /// </summary>
        /// <param name="compare">The aggregate to compare.</param>
        /// <returns>
        /// 	<c>true</c> if the current aggregate instance [is a subset of] [the specified aggregate to compare]; otherwise, <c>false</c>.
        /// </returns>
        bool IsSubsetOf(Aggregate compare);

        /// <summary>
        /// Creates the intersection of the current aggregate instance and another 
        /// specified aggregate.
        /// </summary>
        /// <param name="intersection">The aggregate to create the intersection.</param>
        /// <returns>The created intersection.</returns>
        Aggregate Intersection(Aggregate intersection);

        /// <summary>
        /// Creates the differences between the current aggregate and the 
        /// specified one.
        /// </summary>
        /// <param name="difference">The aggregate to difference with.</param>
        /// <returns>The created aggregate.</returns>
        Aggregate Difference(Aggregate difference);

        /// <summary>
        /// Creates the union of the current aggregate instance and another 
        /// specified aggregate.
        /// </summary>
        /// <param name="union">The aggregate to create the union.</param>
        /// <returns>The created union.</returns>
        Aggregate Union(Aggregate union);

        /// <summary>
        /// Creates the cross product of the current aggregate instance and another
        /// specified aggregate.
        /// </summary>
        /// <param name="aggregate">The other aggregate for creating the cross product.</param>
        /// <returns>The created cross product.</returns>
        Point2DCollection CrossProduct(Aggregate aggregate);

        /// <summary>
        /// Compares the current instance of an aggregate to another one.
        /// </summary>
        /// <param name="compare">The aggregate to compare.</param>
        /// <returns>True, if the current aggregate data is even to the specified
        /// aggregate data otherwise, false.</returns>
        bool CompareTo(Aggregate compare);
    }
}